// @/utils/dynamicRoutes/index.ts
import React from "react";
import type { DynamicRoutes } from "./typing";
import auth from "../plugins/auth";
import wrappers from "@/wrappers/auth";
import { dynamicRoutes } from "../../config/routes/index";

const pathComponent = (component: string): any => {
  return new Promise((resolve, reject): any => {
    import(`@/pages/${component}.jsx`)
      .then((module) => {
        resolve(module);
      })
      .catch((error) => {
        console.log("页面未找到文件", error);
        resolve(import(`@/pages/404`));
      });
  });
};

// 遍历循环
const menuCh = (arr: any) => {
  arr.forEach((t: any) => {
    if (Array.isArray(t.children) && t.children.length > 0) menuCh(t.children);
  });
};

export function parseRoutes(routesRaw: DynamicRoutes.RouteRaw[]) {
  const defaultData = JSON.parse(JSON.stringify(routesRaw));

  const defaultRoutes = filterAsyncRouter(defaultData, false, true);

  return defaultRoutes;
}
// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(
  asyncRouterMap: DynamicRoutes.RouteRaw[],
  lastRouter: any = false,
  type = false
) {
  return asyncRouterMap.filter(async (route) => {
    if (type && route.children && route.menuType == "M") {
      route.children = filterChildren(route.children, route);
    }

    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component != "Layout") {
        const Component = React.lazy(() => pathComponent(route.component));
        route.element = <React.Suspense>{Component && <Component />}</React.Suspense>;
      }
    }

    route.activeMenu = route?.activeMenu;
    route.hidden = route?.hidden;
    route.name = route?.meta?.title || "";
    route.label = route?.meta?.title || "";
    route.key = route?.path.includes("/") ? route?.path : "/" + route?.path;

    // const finds: any = dynamicRoutes.find((y: any) => y.activeMenu == route.path);
    // if (finds) {
    //   const Component = React.lazy(() => pathComponent(finds.component));
    //   finds.element = <React.Suspense>{Component && <Component />}</React.Suspense>;
    //   console.log(await pathComponent(finds.component), finds.component);

    //   if (Array.isArray(route.children)) {
    //     route.children.push(finds);
    //   } else {
    //     route.children = [finds];
    //   }
    // }

    route.wrappers = ["@/wrappers/auth"];
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type);
    } else {
      delete route["children"];
      delete route["redirect"];
    }
    return true;
  });
}

function filterChildren(childrenMap: DynamicRoutes.RouteRaw[], lastRouter: any = false) {
  var children: DynamicRoutes.RouteRaw[] = [];
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === "ParentView" && !lastRouter) {
        el.children.forEach((c) => {
          if (el.menuType == "C" && el.component == "Layout") {
            c.path = c.path;
          } else {
            c.path = el.path + "/" + c.path;
          }

          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c));
          }
          children.push(c);
        });
        return;
      }
    }

    if (lastRouter) {
      if (el.menuType == "C" && el.component == "Layout") {
        el.path = el.path;
      } else {
        el.path = lastRouter.path + "/" + el.path;
      }
    }
    const Component = React.lazy(() => pathComponent(el.component));
    el.element = <React.Suspense>{Component && <Component />}</React.Suspense>;
    el.wrappers = ["@/wrappers/auth"];
    children = children.concat(el);
  });
  return children;
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes: DynamicRoutes.RouteRaw[]) {
  const res: any = [];
  routes.forEach((route) => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route);
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route);
      }
    }
  });
  return res;
}
